<?php

// +----------------------------------------------------------------------
// | 版权所有 2017-2027 云南环拓科技有限公司，并保留所有权利。
// +----------------------------------------------------------------------
// | Copyright (c) 2017-2027 http://www.yn123.com All rights reserved.
// +----------------------------------------------------------------------
// | Notice: This code is not open source, it is strictly prohibited
// |         to distribute the copy, otherwise it will pursue its
// |         legal responsibility.
// | 注意：  这不是一个自由软件！您只能在不用于商业目的的前提下对程序代码进行修改和使用,
// |        不允许对程序代码以任何形式任何目的的再发布。
// +----------------------------------------------------------------------
// | Author: feraner <feraner@163.com>
// | Date: 2018/11/26
// +----------------------------------------------------------------------

namespace app\common\tools;


use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;

/**
 *
 * Class ExportExcel
 * @package app\common\logic
 * @author feraner<feraner@163.com>
 * @date 2018/11/26
 */
class ExportExcel
{

    private $spreadsheetObj = null;


    /**
     * 到处程序入口方法
     * @param $fileName
     * @param $data
     * @throws \PhpOffice\PhpSpreadsheet\Exception
     * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
     */
    public function exportDataToXls($fileName, $data)
    {
        $this->spreadsheetObj = new Spreadsheet();

        $this->setXlsMateInfo()
            ->setColumns($data)
            ->setValues($data)
            ->setTitle($fileName);

        if (\app\common\facade\Arr::has($data, 'otherExportList')) {
            $this->handleOtherExportList($data);
        }

        $this->spreadsheetObj->setActiveSheetIndex(0);

        //防止导出中文乱码
        ob_end_clean();
        $this->handleHeader($fileName);
        $writer = IOFactory::createWriter($this->spreadsheetObj, 'Xls');
        $writer->save('php://output');
    }

    /**
     * 处理一张xls 有多个工作表区
     * @param $data
     * @throws \PhpOffice\PhpSpreadsheet\Exception
     */
    private function handleOtherExportList($data)
    {
        $otherExportList = \app\common\facade\Arr::get($data, 'otherExportList', []);
        foreach ($otherExportList as $other)
        {
            $temp = new Worksheet();
            $this->spreadsheetObj->addSheet($temp, \app\common\facade\Arr::get($other, 'sheetIndex'));
            $this->setColumns($other, \app\common\facade\Arr::get($other, 'sheetIndex'))
                ->setValues($other, \app\common\facade\Arr::get($other, 'sheetIndex'))
                ->setTitle(
                    \app\common\facade\Arr::get($other, 'sheetTitle'),
                    \app\common\facade\Arr::get($other, 'sheetIndex')
                );
        }

    }


    /**
     * 设置列标题
     * @param $data
     * @return $this
     */
    private function setColumns($data, $sheetIndex = 0)
    {
        $titleArr = \app\common\facade\Arr::get($data, 'cellTitle', []);
        foreach ($titleArr as $key=>$item) {
            $this->spreadsheetObj->setActiveSheetIndex($sheetIndex)
                ->setCellValueByColumnAndRow(($key+1), 1, \app\common\facade\Arr::get($item, 'name'));
        }

        $this->spreadsheetObj->getActiveSheet()->getRowDimension('1')->setRowHeight(40);
        return $this;
    }


    /**
     * @param $data
     * @return $this
     */
    private function setValues($data, $sheetIndex = 0)
    {
        $titleArr = \app\common\facade\Arr::get($data, 'cellTitle', []);
        $listData = \app\common\facade\Arr::get($data, 'list', []);
        foreach ($listData as $key=>$item) {
            foreach ($titleArr as $index=>$title) {
                $setValue = \app\common\facade\Arr::get($item, $title['dataName']);
                if (\app\common\facade\Arr::has($title, 'handle', '')) {
                    $handleFunction = $title['handle'];
                    if (\app\common\facade\Arr::has($title, 'appendDataName')) {
                        $setValue = $this->$handleFunction($setValue, \app\common\facade\Arr::get($title, 'appendDataName'));
                    } else {
                        $setValue = $this->$handleFunction($setValue);
                    }
                }
                $this->spreadsheetObj->setActiveSheetIndex($sheetIndex)
                    ->setCellValueByColumnAndRow(($index+1), $key+2, $setValue);
            }
        }

        return $this;
    }

    /**
     * @param $title
     * @return $this
     */
    private function setTitle($title, $sheetIndex = 0)
    {
        $this->spreadsheetObj->getActiveSheet()
            ->setTitle($title);
        $this->spreadsheetObj->setActiveSheetIndex($sheetIndex);
        $this->spreadsheetObj->getActiveSheet()
            ->getDefaultColumnDimension()
            ->setWidth(20);
        return $this;
    }

    private function setXlsMateInfo()
    {
        $this->spreadsheetObj->getProperties()
            ->setCreator('掌上汇同城')
            ->setLastModifiedBy('Maarten Balliauw')
            ->setTitle('Office 2007 XLSX Test Document')
            ->setSubject('Office 2007 XLSX Test Document')
            ->setDescription('Test document for Office 2007 XLSX')
            ->setKeywords('office 2007 openxml php')
            ->setCategory('程序导出列表');
        return $this;
    }





    /**
     * @param $fileName
     */
    private function handleHeader($fileName)
    {

        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename="' . $fileName . '.xls"');
        header('Cache-Control: max-age=0');
        header('Cache-Control: max-age=1');
        header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
        header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
        header('Cache-Control: cache, must-revalidate');
        header('Pragma: public');
    }

    private function handleDate($value)
    {
        return date('Y-m-d H:i:s', $value);
    }

    private function handleMoney($value)
    {
        return ncPriceFormat($value);
    }

    private function handleMonth($value)
    {
        return date('Y-m', $value);
    }

    private function handleDay($value)
    {
        return date('Y-m-d', $value);
    }

    private function handleDayRange($start, $end)
    {
        return date('Y-m-d', $start) . '至' . date('Y-m-d', $end);
    }

    private function handleOrderSn($value)
    {
        return $value . ' ';
    }

    private function handlePayDesc($value)
    {
        return $value ? "已结算" : "未结算";
    }

    private function handleIsPayDelivery($value)
    {
        return $value ? "货到付款" : "在线支付";
    }

    private function handlePrintState($value)
    {
        return $value ? '已打印' : '未打印';
    }

    //结算比例处理
    private function handleUnit($value, $bili)
    {
        return sprintf('%.2f', ($value * $bili));
    }

    private function handleCommission($value)
    {
        return $value . '%';
    }

}
